<template>
  <view class="container">
    <!-- 1. 相机页面 -->
    <view v-if="pageState === 'camera'" class="camera-container">
      <!-- 1.1 相机预览区域 -->
      <view class="camera-wrapper">
        <canvas v-show="!singlePhotoPath && showCamera" ref="canvasElement" class="camera-canvas"></canvas>
        <!-- singlePhotoPath 用于单张照片确认（如穴位识别） -->
        <image v-if="singlePhotoPath" :src="singlePhotoPath" class="preview-image" mode="heightFix" />
        <view v-if="!singlePhotoPath" class="camera-prompt">
          <text class="prompt-text">{{ currentTextTips }}</text>
        </view>
        <image v-if="!singlePhotoPath" class="guide-image" :src="currentOverlay" />
      </view>

      <!-- 1.2 底部控制区域 -->
      <view class="bottom-controls">
        <!-- 单张照片的确认/重拍UI -->
        <view v-if="singlePhotoPath" class="confirm-actions">
          <view class="button-wrapper" @click="retake"><text class="btn-text">重拍</text></view>
          <view class="button-wrapper" @click="confirm"><text class="btn-text primary">确认使用</text></view>
        </view>
        <!-- 拍照时的UI -->
        <view v-else>
          <!-- 穴位识别的身体部位选择器 -->
          <view v-if="cameraSource === 'acupoint'" class="part-selector">
            <scroll-view scroll-x="true" class="scroll-view" show-scrollbar="false">
              <view
                v-for="(part, index) in bodyParts"
                :key="part.id"
                class="part-item"
                :class="{ active: active_id === part.id }"
                @click="selectPart(index, part.id)"
                >{{ part.body_name }}</view
              >
            </scroll-view>
          </view>
          <view class="action-buttons">
            <view class="button-wrapper" @click="takePhoto">
              <image src="/static/icons/posture.png" class="icon-placeholder" mode="aspectFit"></image>
              <text class="btn-text">正确姿势</text>
            </view>
            <view class="shutter-button-wrapper" @click="takePhoto" :class="{ disabled: !showCamera }">
              <view class="shutter-button"></view>
            </view>
            <view class="button-wrapper" @click="switchCamera">
              <image src="/static/icons/phone.png" class="icon-placeholder" mode="aspectFit"></image>
              <text class="btn-text">切换</text>
            </view>
          </view>
        </view>
      </view>
    </view>

    <!-- [新增] 2. 多照片确认页面 -->
    <view v-else-if="pageState === 'multiConfirm'" class="confirm-page-container">
      <view class="confirm-page-header">
        <text class="header-title">{{ pageTitle }}</text>
      </view>
      <scroll-view scroll-y class="confirm-scroll-view">
        <!-- [新增] 内部包裹层，用于处理内边距 -->
        <view class="scroll-content-wrapper">
          <view v-for="(photo, index) in capturedPhotos" :key="index" class="photo-item">
            <text class="photo-label">{{ currentWorkflow.steps[index].label }}</text>
            <image :src="photo.path" class="photo-preview" mode="aspectFill"></image>
          </view>
        </view>
      </scroll-view>
      <view class="confirm-page-footer">
        <button class="footer-btn retake-btn" :disabled="isPolling" @click="retakeMultiPhotos">重新拍摄</button>
        <button class="footer-btn confirm-btn" :loading="isPolling" :disabled="isPolling" @click="confirmMultiPhotos">
          {{ isPolling ? '分析中...' : '确认使用' }}
        </button>
      </view>
    </view>

    <!-- [REFACTORED] 3. 问卷调查页面 -->
    <view v-else-if="pageState === 'questionnaire'" class="questionnaire-page">
      <view class="questionnaire-header">
        <view class="header-text">回答下列问题，以便更加了解您的身体状况。</view>
        <view class="header-text">保证检测结果的准确性。</view>
      </view>

      <scroll-view scroll-y class="questionnaire-scroll">
        <view class="question-list" :class="{ answering: isAnswering }">
          <view v-for="question in questionnaireData.questions" :key="question.subjectId" class="question-card">
            <view class="question-title-wrapper">
              <text class="question-title">{{ question.subjectTitle }}</text>
            </view>
            <view class="answer-options">
              <template v-if="question.subjectType === 0">
                <input
                  v-model="answers[question.subjectId]"
                  class="age-input"
                  type="number"
                  :placeholder="question.answer[0].answerTitle"
                  @blur="handleAgeInput(question.subjectId)" />
              </template>

              <template v-if="question.subjectType === 1">
                <view
                  v-for="option in question.answer"
                  :key="option.answerCode"
                  class="answer-btn"
                  :class="{ active: answers[question.subjectId] === option.answerCode }"
                  @click="selectAnswer(question.subjectId, option.answerCode)">
                  {{ option.answerTitle }}
                </view>
              </template>
            </view>
          </view>
        </view>
      </scroll-view>
    </view>

    <!-- 3. 结果展示页面 -->
    <view v-else>
      <!-- 如果是舌诊，显示舌诊结果页 -->
      <tongue-results-page v-if="cameraSource === 'tongue'" :result-data="analysisResult" @restart="restart" />
      <!-- 如果是面诊，显示面诊结果页 -->
      <face-results-page v-if="cameraSource === 'face'" :result-data="analysisResult" @restart="restart" />

      <!-- 否则，显示原来的穴位识别结果页 -->
      <results-page
        v-else
        :photo-path="analysisResult.picUrl"
        :acupoint-list="analysisResult.acupointList"
        :link-to="analysisResult.linkTo"
        @restart="restart" />
    </view>
  </view>
</template>

<script>
  // 1. 导入新组件
  import ResultsPage from './ResultsPage.vue'
  import TongueResultsPage from './TongueResultsPage.vue'
  import FaceResultsPage from './FaceResultsPage.vue'
  import { upload } from '@/utils/request.js'
  import {
    getpartlist,
    createAcupoint,
    checkStatus,
    getResult,
    createTonguet,
    checkTongueStatus,
    getTongueResult,
    createFaceDiagnosis,
    answerQuestion,
    getFinalFaceResult
  } from '@/api/acupoint.js'
  import { useUserStore } from '@/store/user.js'
  export default {
    // 2. 注册新组件
    components: {
      ResultsPage,
      TongueResultsPage,
      FaceResultsPage
    },
    data() {
      return {
        // --- 页面状态管理 ---
        pageState: 'camera', // 'camera', 'multiConfirm', 'questionnaire', 'results'
        cameraSource: 'acupoint', // 'acupoint', 'tongue', 'face'

        // --- 相机核心 ---
        showCamera: false,
        isFrontCamera: false,
        stream: null,
        videoElement: null,
        canvasContext: null,
        animationFrameId: null,
        // [新增] 存储canvas/容器的尺寸，用于适配不同屏幕
        screenWidth: 0,
        screenHeight: 0,

        // --- 单张照片工作流 (穴位识别) ---
        singlePhotoPath: '', // 仅用于单张照片的临时路径
        bodyParts: [],
        activePartIndex: 0,
        active_id: 0,

        // --- 问卷相关数据 ---
        questionnaireData: {
          faceId: null,
          id: null, // 保存面诊记录的ID
          questions: []
        },
        answers: {},
        isAnswering: false, //防止重复提交的状态锁

        // --- 多步骤拍照工作流 ---
        photoWorkflows: {
          tongue: {
            title: '舌诊',
            steps: [
              { label: '舌上照片', prompt: '请将舌面完整平展，对准参考线', overlay: '/static/overlays/01.png' },
              {
                label: '舌下照片',
                prompt: '请卷起舌头，露出舌下，对准参考线',
                overlay:
                  'https://hyj-ehos.oss-cn-guangzhou.aliyuncs.com/upload/material/20250401/b39bdaeb402f4373b923cdfb17062552.png'
              }
            ]
          },
          face: {
            title: '面诊',
            steps: [
              { label: '正脸照片', prompt: '请正对摄像头，面部完全入镜', overlay: '/static/overlays/face_01.png' },
              { label: '左侧脸照片', prompt: '请向右转头，露出左侧脸', overlay: '/static/overlays/face_02.png' },
              { label: '右侧脸照片', prompt: '请向左转头，露出右侧脸', overlay: '/static/overlays/face_02.png' }
            ]
          }
        },
        currentStepIndex: 0, // 当前拍照步骤的索引
        capturedPhotos: [], // 存储已拍摄照片的数组 { path: 'base64...' }

        // --- 结果与轮询 ---
        analysisResult: { picUrl: '', acupointList: [], linkTo: {} },
        appoint_no: null,
        pollCount: 0,
        maxPollCount: 10,
        interval: 1000,
        pollTimer: null,
        isPolling: false
      }
    },
    computed: {
      // 判断当前是否为多步骤工作流
      isMultiStepFlow() {
        return !!this.photoWorkflows[this.cameraSource]
      },
      // 获取当前工作流配置
      currentWorkflow() {
        return this.photoWorkflows[this.cameraSource]
      },
      // 获取当前步骤的配置
      currentStepConfig() {
        if (!this.isMultiStepFlow) return null
        return this.currentWorkflow.steps[this.currentStepIndex]
      },
      // 动态页面标题
      pageTitle() {
        return this.isMultiStepFlow ? this.currentWorkflow.title : '穴位识别'
      },
      // 动态提示文字
      currentTextTips() {
        if (this.isMultiStepFlow) {
          return this.currentStepConfig?.prompt || ''
        }
        return this.bodyParts[this.activePartIndex]?.remark || '请对准身体部位拍照'
      },
      // 动态引导图
      currentOverlay() {
        if (this.isMultiStepFlow) {
          return this.currentStepConfig?.overlay || ''
        }
        return this.bodyParts[this.activePartIndex]?.img_url || ''
      },
      userStore() {
        return useUserStore()
      },
      userInfo() {
        return this.userStore.userInfo
      }
    },
    // onLoad 生命周期函数
    onLoad(options) {
      // 检查 options 对象和 source 参数是否存在
      if (options && options.source) {
        this.cameraSource = options.source
        console.log('当前相机来源:', this.cameraSource)
      } else {
        console.warn('未指定相机来源，将使用默认逻辑。')
      }

      // 根据来源可以做一些初始化操作
      this.initializeBasedOnSource()
    },
    onReady() {
      if (this.pageState === 'camera') {
        this.initCamera()
        //new VConsole();
      }
    },
    onUnload() {
      this.stopCamera()
    },
    methods: {
      initializeBasedOnSource() {
        this.resetWorkflowState()
        if (this.cameraSource === 'acupoint') {
          this.getpartListData()
        }
      },
      resetWorkflowState() {
        this.currentStepIndex = 0
        this.capturedPhotos = []
        this.singlePhotoPath = ''
        this.questionnaireData = { faceId: null, id: null, questions: [] }
        this.answers = {}
        this.isAnswering = false
        this.isPolling = false
      },
      async getpartListData() {
        const res = await getpartlist()
        if (res.result && res.result.length > 0) {
          this.bodyParts = res.result
          this.active_id = res.result[0].id
        }
      },
      // --- 相机 & 确认页面方法 ---
      async initCamera() {
        this.stopCamera()
        try {
          // [MODIFIED] 使用 uni.createSelectorQuery 获取预览容器的实际尺寸
          const rect = await new Promise(resolve => {
            uni
              .createSelectorQuery()
              .in(this)
              .select('.camera-wrapper')
              .boundingClientRect(data => {
                if (data) {
                  // 将获取到的宽高存储到 data 中
                  this.screenWidth = data.width
                  this.screenHeight = data.height
                } else {
                  // 如果获取失败，则回退到使用窗口尺寸
                  this.screenWidth = window.innerWidth
                  this.screenHeight = window.innerHeight
                  console.warn('获取 .camera-wrapper 尺寸失败, 使用 window 尺寸作为备用。')
                }
                resolve(data)
              })
              .exec()
          })

          const canvas = await this.getCanvasElement()
          if (!canvas) return

          // [MODIFIED] 设置 canvas 的绘图表面（分辨率）与容器尺寸一致
          canvas.width = this.screenWidth
          canvas.height = this.screenHeight

          this.canvasContext = canvas.getContext('2d')
          this.videoElement = document.createElement('video')
          this.videoElement.setAttribute('playsinline', true)
          this.videoElement.muted = true
          this.videoElement.autoplay = true
          this.videoElement.style.display = 'none'
          document.body.appendChild(this.videoElement)
          this.stream = await navigator.mediaDevices.getUserMedia({
            video: { facingMode: this.isFrontCamera ? 'user' : 'environment' }
          })
          this.videoElement.srcObject = this.stream
          this.videoElement.onloadedmetadata = () => {
            this.videoElement.play()
            this.showCamera = true
            this.startDrawing()
          }
        } catch (error) {
          console.error('相机启动失败:', error)
          uni.showModal({ title: '相机错误', content: '无法访问相机，请检查浏览器权限。', showCancel: false })
        }
      },
      startDrawing() {
        if (!this.showCamera || this.singlePhotoPath) {
          if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId)
          this.animationFrameId = null
          return
        }
        const ctx = this.canvasContext
        // [MODIFIED] 使用存储的容器/屏幕尺寸进行绘制
        const canvasWidth = this.screenWidth
        const canvasHeight = this.screenHeight

        ctx.clearRect(0, 0, canvasWidth, canvasHeight)
        if (this.isFrontCamera) {
          ctx.save()
          ctx.translate(canvasWidth, 0)
          ctx.scale(-1, 1)
          // [MODIFIED] 拉伸视频帧以填满整个 canvas
          ctx.drawImage(this.videoElement, 0, 0, canvasWidth, canvasHeight)
          ctx.restore()
        } else {
          // [MODIFIED] 拉伸视频帧以填满整个 canvas
          ctx.drawImage(this.videoElement, 0, 0, canvasWidth, canvasHeight)
        }
        this.animationFrameId = requestAnimationFrame(this.startDrawing.bind(this))
      },
      getCanvasElement() {
        return new Promise(resolve => {
          uni
            .createSelectorQuery()
            .in(this)
            .select('.camera-canvas')
            .node(res => resolve(res ? res.node : null))
            .exec()
        })
      },
      takePhoto() {
        if (!this.showCamera || !this.videoElement) return
        const tempCanvas = document.createElement('canvas')
        const ctx = tempCanvas.getContext('2d')

        // [MODIFIED] 使用存储的容器/屏幕尺寸来创建临时画布
        const canvasWidth = this.screenWidth
        const canvasHeight = this.screenHeight

        // [MODIFIED] 确保临时画布的分辨率与屏幕上看到的一致
        tempCanvas.width = canvasWidth
        tempCanvas.height = canvasHeight

        if (this.isFrontCamera) {
          ctx.save()
          ctx.translate(canvasWidth, 0)
          ctx.scale(-1, 1)
          // [MODIFIED] 将视频帧绘制到临时画布上，同样进行拉伸
          ctx.drawImage(this.videoElement, 0, 0, canvasWidth, canvasHeight)
          ctx.restore()
        } else {
          // [MODIFIED] 将视频帧绘制到临时画布上，同样进行拉伸
          ctx.drawImage(this.videoElement, 0, 0, canvasWidth, canvasHeight)
        }
        const photoBase64 = tempCanvas.toDataURL('image/jpeg', 0.9)

        if (this.isMultiStepFlow) {
          // 多步骤流程
          this.capturedPhotos.push({ path: photoBase64 })
          this.currentStepIndex++

          if (this.currentStepIndex >= this.currentWorkflow.steps.length) {
            // 所有照片已拍完
            this.stopCamera()
            this.pageState = 'multiConfirm'
          } else {
            // 进入下一步，无需操作，UI会自动更新
            uni.showToast({ title: `请准备拍摄: ${this.currentStepConfig.label}`, icon: 'none', duration: 1500 })
          }
        } else {
          // 单张照片流程（穴位识别）
          this.singlePhotoPath = photoBase64
          this.stopCamera()
        }
      },
      // --- 单张照片工作流方法 ---
      selectPart(index, id) {
        this.activePartIndex = index
        this.active_id = id
      },
      stopCamera() {
        if (this.animationFrameId) {
          cancelAnimationFrame(this.animationFrameId)
          this.animationFrameId = null
        }
        if (this.stream) {
          this.stream.getTracks().forEach(track => track.stop())
          this.stream = null
        }
        if (this.videoElement && document.body.contains(this.videoElement)) {
          document.body.removeChild(this.videoElement)
          this.videoElement = null
        }
        this.showCamera = false
      },
      switchCamera() {
        this.isFrontCamera = !this.isFrontCamera
        this.initCamera()
      },
      retake() {
        this.singlePhotoPath = ''
        this.pageState = 'camera'
        this.resetWorkflowState()
        this.$nextTick(() => this.initCamera())
      },
      async getResultData() {
        const res = await getResult(this.appoint_no)

        try {
          const response = await getResult(this.appoint_no)
          if (response.code === 200 && response.result) {
            const resultsData = response.result
            // 3. 将结果存入 state, 准备传递给子组件

            this.analysisResult = {
              picUrl: resultsData.pic_url,
              acupointList: resultsData.acupointList.map(point => ({
                ...point,
                xaxis: Number(point.x_axis),
                yaxis: Number(point.y_axis)
              })),
              linkTo: {
                shoppingMallAppId: resultsData.shoppingMallAppId,
                shoppingMallUrl: resultsData.shoppingMallUrl
              }
            }
            // 4. 清空本地照片, 切换页面状态
            this.singlePhotoPath = ''
            this.pageState = 'results'
          } else {
            throw new Error(response.message || '分析服务出错，请稍后重试')
          }
        } catch (error) {
          uni.showToast({ title: error.message, icon: 'none' })
        } finally {
          uni.hideLoading()
        }
      },
      async checkStatusfn() {
        this.pollCount = 0

        const loop = async () => {
          try {
            const res = await checkStatus(this.appoint_no)

            if (res.result && res.result.status === '000') {
              console.log(' 成功状态，停止轮询')
              clearTimeout(this.pollTimer)
              this.pollTimer = null
              this.getResultData()
              // TODO：成功后的处理
              return
            }

            this.pollCount++
            if (this.pollCount >= this.maxPollCount) {
              console.log('已轮询10次仍未成功，视为失败')
              uni.showToast({ title: '分析超时，请稍后再试', icon: 'none' })
              // TODO：失败处理逻辑
              return
            }

            this.pollTimer = setTimeout(loop, this.interval)
          } catch (err) {
            console.error('接口异常', err)
            this.pollCount++
            if (this.pollCount >= this.maxPollCount) {
              console.log(' 接口异常且已达到最大次数，失败')
              // TODO：失败处理逻辑
            } else {
              this.pollTimer = setTimeout(loop, this.interval)
            }
          }
        }

        loop()
      },
      showPoseGuide() {
        this.confirm()
        uni.showModal({
          title: '正确姿势指引',
          content: '请将身体部位对准屏幕中央的白色轮廓线，保持光线充足，点击下方圆形按钮进行拍照。',
          showCancel: false
        })
      },
      async confirm() {
        uni.showLoading({ title: '智能分析中...' })

        upload({
          url: '/api/hospital/upload', // 你的后端上传路径
          filePath: this.singlePhotoPath,
          name: 'file', // 后端接收字段
          showLoading: false,
          formData: {
            bizType: 'user-avatar' // 业务参数，根据后端需求传
          }
        })
          .then(res => {
            console.log('上传成功', res)

            if (res.result && res.result.url) {
              // uni.showToast({ title: '上传成功', icon: 'success' })
              const params = {
                acupoint_id: this.active_id,
                pic_url: res.result.url,
                user_id: this.userInfo.id
              }

              createAcupoint(params).then(res => {
                if (res.result && res.result.appoint_no) {
                  this.appoint_no = res.result.appoint_no
                  this.checkStatusfn()
                }
              })
            }
          })
          .catch(err => {
            console.error('上传失败', err)
          })
      },
      // --- 多照片工作流方法 ---
      retakeMultiPhotos() {
        this.pageState = 'camera'
        this.resetWorkflowState()
        this.$nextTick(() => this.initCamera())
      },
      async confirmMultiPhotos() {
        if (this.isPolling) return // 如果正在轮询，防止重复点击
        uni.showLoading({ title: '正在上传照片...' })

        try {
          // 使用 Promise.all 并行上传所有照片
          const uploadPromises = this.capturedPhotos.map((photo, index) => {
            return upload({
              url: '/api/hospital/upload',
              filePath: photo.path,
              name: 'file',
              showLoading: false,
              formData: {
                bizType: `${this.cameraSource}-${this.currentWorkflow.steps[index].label}`
              }
            })
          })

          const uploadResults = await Promise.all(uploadPromises)

          // 收集所有上传成功的图片URL
          const photoUrls = uploadResults.map(res => {
            if (res.result && res.result.url) {
              return res.result.url
            }
            throw new Error('有照片上传失败，请重试')
          })

          uni.hideLoading()
          uni.showLoading({ title: '智能分析中...' })

          // --- [核心修改] 步骤 2: 根据 cameraSource 调用不同的业务API ---

          let analysisRes = null // 用于存储分析结果
          let params = {} // 用于存储API参数

          if (this.cameraSource === 'tongue') {
            params = {
              tongueFrontImg: photoUrls[0], // 第1张是舌上照片
              tongueBottomImg: photoUrls[1], // 第2张是舌下照片
              user_id: this.userInfo.id
            }
            this.isPolling = true
            const createRes = await createTonguet(params)
            if (createRes && createRes.code === 200 && createRes.result.appoint_no) {
              // 获取到 appoint_no，开始轮询状态
              this.appoint_no = createRes.result.appoint_no
              this.isPolling = true // [MODIFIED] 设置按钮为加载状态
              this.startPollingForTongueResult() // 调用新的轮询方法
            } else {
              uni.showToast({ title: createFaceRes.message, icon: 'none' })
              throw new Error(createRes.message || '创建诊断任务失败')
            }
          } else if (this.cameraSource === 'face') {
            // --- 对接面诊API (示例) ---
            this.isPolling = true
            params = {
              faceImgPath: photoUrls[0], // 第1张是正脸
              faceLeftImgPath: photoUrls[1], // 第2张是左侧脸
              faceRightImgPath: photoUrls[2], // 第3张是右侧脸
              user_id: this.userInfo.id
            }
            const createFaceRes = await createFaceDiagnosis(params)

            if (createFaceRes.code === 200 && createFaceRes.result && createFaceRes.result.subject) {
              this.questionnaireData = {
                faceId: createFaceRes.result.faceId,
                id: createFaceRes.result.id,
                questions: createFaceRes.result.subject
              }
              this.initializeAnswers()
              this.pageState = 'questionnaire'
            } else {
              uni.showToast({ title: createFaceRes.message, icon: 'none' })
              throw new Error(createFaceRes.message || '面部识别服务出错')
            }
          } else {
            throw new Error(`未知的诊断类型: ${this.cameraSource}`)
          }

          // 步骤 3: 处理分析结果并跳转页面
          if (analysisRes && analysisRes.code === 200 && analysisRes.result) {
            // [修改] 为不同诊断类型准备不同的结果数据结构
            if (this.cameraSource === 'tongue') {
              // 将整个 result 对象存起来，并附加用户信息
              this.analysisResult = analysisRes.result
              this.analysisResult.userInfo = this.userInfo // 把用户信息也传过去
            } else if (this.cameraSource === 'face') {
              // ... (face result handling)
              this.analysisResult = {
                picUrl: analysisRes.result.report_image_url || photoUrls[0]
                // ... other face result fields
              }
            }

            this.pageState = 'results' // 切换到结果页
          } else {
            // API返回错误或失败
            // throw new Error(analysisRes.message || "智能分析服务出错，请稍后重试");
          }
        } finally {
          uni.hideLoading()
          this.isPolling = false // [MODIFIED] 设置按钮为加载状态
        }
      },

      // --- [REFACTORED] 问卷核心逻辑 ---

      initializeAnswers() {
        this.answers = this.questionnaireData.questions.reduce((acc, q) => {
          acc[q.subjectId] = null
          return acc
        }, {})
      },

      // 用户点击单选按钮
      selectAnswer(questionId, answerCode) {
        if (this.isAnswering) return // 如果正在提交，则忽略点击

        // 立即更新UI
        this.answers[questionId] = answerCode

        // 提交答案
        this.submitSingleAnswer(questionId, answerCode)
      },

      // 用户输入年龄后失焦
      handleAgeInput(questionId) {
        if (this.isAnswering) return

        const age = this.answers[questionId]
        if (!age || age <= 0) {
          uni.showToast({ title: '请输入有效的年龄', icon: 'none' })
          return
        }
        this.submitSingleAnswer(questionId, age)
      },

      async submitSingleAnswer(questionId, answerValue) {
        this.isAnswering = true
        uni.showLoading({ title: '请稍候...', mask: true })

        try {
          const payload = {
            id: this.questionnaireData.id,
            faceId: this.questionnaireData.faceId,
            answer: [
              {
                subjectId: String(questionId),
                answerCode: String(answerValue)
              }
            ]
          }

          const res = await answerQuestion(payload)

          if (res.code === 200 && res.result) {
            if (res.result.isFinalResult === '1') {
              await this.fetchFinalFaceResult()
            } else if (res.result.subject && res.result.subject.length > 0) {
              this.questionnaireData.questions = res.result.subject
              this.initializeAnswers()
            } else {
              await this.fetchFinalFaceResult()
            }
          } else {
            throw new Error(res.message || '提交答案失败')
          }
        } catch (err) {
          uni.showToast({ title: err.message, icon: 'none' })
        } finally {
          this.isAnswering = false
          uni.hideLoading()
        }
      },

      async fetchFinalFaceResult() {
        uni.showLoading({ title: '正在生成最终报告...' })
        try {
          const finalRes = await getFinalFaceResult(this.questionnaireData.faceId)

          if (finalRes.code === 200 && finalRes.result) {
            this.analysisResult = { ...finalRes.result, userInfo: this.userInfo }
            this.pageState = 'results'
          } else {
            throw new Error(finalRes.message || '获取报告失败')
          }
        } catch (err) {
          uni.showToast({ title: err.message, icon: 'none' })
        } finally {
          uni.hideLoading()
        }
      },
      // [新增] 舌诊结果的轮询方法
      startPollingForTongueResult() {
        this.pollCount = 0 // 重置轮询计数器
        clearTimeout(this.pollTimer) // 清除可能存在的旧定时器

        const loop = async () => {
          try {
            console.log(`第 ${this.pollCount + 1} 次轮询舌诊状态, appoint_no: ${this.appoint_no}`)
            const statusRes = await checkTongueStatus(this.appoint_no)
            console.log('轮询状态结果:', statusRes)

            // 检查状态是否成功 ('000')
            if (statusRes.result && statusRes.result.status === '000') {
              console.log('舌诊分析成功，停止轮询，准备获取最终结果。')
              clearTimeout(this.pollTimer)
              this.pollTimer = null

              // 获取最终结果
              const finalResultRes = await getTongueResult(this.appoint_no)

              if (finalResultRes && finalResultRes.code === 200 && finalResultRes.result) {
                // 将整个 result 对象存起来，并附加用户信息
                this.analysisResult = finalResultRes.result
                this.analysisResult.userInfo = this.userInfo

                this.pageState = 'results' // 切换到结果页
                uni.hideLoading()
              } else {
                throw new Error(finalResultRes.message || '获取诊断报告失败')
              }
              this.isPolling = false // [MODIFIED] 成功后重置按钮状态
              return // 成功，退出循环
            }
            // 检查状态是否为 '201' (错误)
            if (statusRes.result && statusRes.result.status === '101') {
              clearTimeout(this.pollTimer)
              uni.hideLoading()
              this.isPolling = false // [MODIFIED] 成功后重置按钮状态
              uni.showToast({ title: statusRes.result.msg, icon: 'none' })
              return
            }

            // 检查是否达到最大轮询次数
            this.pollCount++
            if (this.pollCount >= this.maxPollCount) {
              clearTimeout(this.pollTimer)
              this.isPolling = false // [MODIFIED] 成功后重置按钮状态
              uni.showToast({ title: '分析超时，请稍后再试', icon: 'none' })
              throw new Error('分析超时，请稍后再试')
            }

            // 未成功且未超时，继续轮询
            this.pollTimer = setTimeout(loop, this.interval)
          } catch (err) {
            console.error('轮询过程中发生错误:', err)
            clearTimeout(this.pollTimer)
            this.isPolling = false // [MODIFIED] 成功后重置按钮状态
            uni.hideLoading()
            uni.showToast({ title: err.message || '分析失败，请重试', icon: 'none' })
          }
        }

        loop() // 启动第一次轮询
      },

      // --- 响应子组件事件 ---
      restart() {
        this.analysisResult = { picUrl: '', acupointList: [], linkTo: {} }
        this.pageState = 'camera'
        this.resetWorkflowState()
        clearTimeout(this.pollTimer)
        this.pollTimer = null
        this.$nextTick(() => this.initCamera())
      }
    }
  }
</script>

<style lang="scss" scoped>
  .container {
    display: flex;
    flex-direction: column;
    height: 100vh;
    width: 100vw;
    background-color: #000;
    overflow: hidden;
  }
  .camera-container {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
  }
  .camera-wrapper {
    flex: 1;
    position: relative;
    overflow: hidden;
    background-color: #000;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .camera-canvas,
  .preview-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
  }

  .camera-prompt {
    position: absolute;
    top: 20px;
    left: 0;
    right: 0;
    z-index: 5;
    text-align: center;
    pointer-events: none; /* 让下层元素可以被点击 */
  }

  .prompt-text {
    color: #fff;
    padding: 6px 15px;

    font-size: 14px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  }

  .guide-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    opacity: 0.8;
  }

  .bottom-controls {
    background-color: rgba(0, 0, 0, 0.5);
    color: #fff;
    padding-bottom: constant(safe-area-inset-bottom);
    padding-bottom: env(safe-area-inset-bottom);
    padding-top: 10px;
    z-index: 10;
    position: relative;

    display: flex;
    flex-direction: column;

    justify-content: center;
    box-sizing: border-box;
    flex-shrink: 0;

    transition: all 0.2s ease-in-out;
  }

  .part-selector {
    width: 100%;
    margin-bottom: 20px;
    overflow: visible;
  }
  .scroll-view {
    white-space: nowrap;
    width: 100%;
    text-align: center;
  }
  .part-item {
    display: inline-block;
    color: #ccc;
    padding: 8px 15px;
    font-size: 15px;
    transition: all 0.2s ease;
  }
  .part-item.active {
    color: #4cd964;
    font-weight: bold;
    transform: scale(1.15);
  }
  .action-buttons {
    display: flex;
    justify-content: space-around;
    align-items: center;
    width: 100%;
    padding: 0 20px 10px;
    box-sizing: border-box;
  }
  .button-wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
    color: white;
    flex: 1;
    text-align: center;
    cursor: pointer;
  }
  .icon-placeholder {
    width: 32px;
    height: 32px;
    background-color: rgba(255, 255, 255, 0.2);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    color: #fff;
  }
  .btn-text {
    font-size: 13px;
    margin-top: 5px;
    color: #fff;
  }
  .btn-text.primary {
    color: #4cd964;
    font-weight: bold;
  }
  .shutter-button-wrapper {
    width: 70px;
    height: 70px;
    border-radius: 50%;
    background-color: #fff;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 4px;
    box-sizing: border-box;
    cursor: pointer;
    transition: transform 0.1s ease;
  }
  .shutter-button-wrapper:active {
    transform: scale(0.95);
  }
  .shutter-button-wrapper.disabled {
    opacity: 0.5;
    pointer-events: none;
  }
  .shutter-button {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background-color: #fff;
    border: 3px solid #000;
    box-sizing: border-box;
  }
  .confirm-actions {
    display: flex;
    justify-content: space-around;
    align-items: center;
    width: 100%;
    /* 保持一个最小高度，让确认按钮区域不至于太小 */
    min-height: 95px;
    padding-bottom: 10px;
  }
  .confirm-actions .button-wrapper .btn-text {
    font-size: 17px;
  }

  .confirm-page-container {
    display: flex;
    flex-direction: column;
    height: 100vh;
    width: 100vw;
    padding-bottom: 160rpx;
    background-color: #f7f8fa;
  }

  .confirm-page-header {
    text-align: center;
    padding: 12px 0;
    font-size: 18px;
    font-weight: 500;
    background-color: #fff;
    position: relative;
    border-bottom: 1px solid #ebedf0;
    flex-shrink: 0;
  }

  .confirm-scroll-view {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    box-sizing: border-box;
  }

  .scroll-content-wrapper {
    padding: 16px;
    box-sizing: border-box;
  }
  .photo-item {
    background-color: #fff;
    border-radius: 8px;
    padding: 16px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  }

  .photo-label {
    font-size: 16px;
    color: #323233;
  }

  .photo-preview {
    width: 80px;
    height: 80px;
    border-radius: 6px;
    background-color: #eee;
  }

  .confirm-page-footer {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    gap: 24rpx;
    padding: 24rpx 30rpx;
    background-color: #fff;
    border-top: 1rpx solid #f0f0f0;
    padding-bottom: calc(24rpx + constant(safe-area-inset-bottom));
    padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
    z-index: 100;
  }
  .footer-btn {
    flex: 1;
    height: 44px;
    line-height: 44px;
    border-radius: 22px;
    font-size: 16px;
    margin: 0;
  }
  .retake-btn {
    background-color: #f2f3f5;
    color: #323233;
    border: 1px solid #ebedf0;
  }
  .confirm-btn {
    background-color: #007aff;
    color: #fff;
  }

  .questionnaire-page {
    display: flex;
    flex-direction: column;
    height: 100vh;
    width: 100vw;
    background-color: #afa0ec;
    padding: 30rpx;
    box-sizing: border-box;
  }

  .questionnaire-header {
    padding: 20rpx 0 40rpx;
    color: #fff;
    text-align: left;
    .header-text {
      font-size: 32rpx;
      line-height: 1.5;
    }
  }

  .questionnaire-scroll {
    flex: 1;
    height: 0;
  }

  .question-list.answering {
    pointer-events: none;
    opacity: 0.7;
  }

  .question-card {
    background-color: #fff;
    border-radius: 20rpx;
    padding: 40rpx 30rpx;
    margin-bottom: 30rpx;
  }

  .question-title-wrapper {
    display: flex;
    align-items: center;
    margin-bottom: 40rpx;
    .question-title {
      font-size: 34rpx;
      font-weight: 600;
      color: #333;
    }
  }

  .answer-options {
    display: flex;
    flex-direction: column;
    gap: 30rpx;
  }

  .age-input {
    width: 100%;
    height: 90rpx;
    line-height: 90rpx;
    text-align: center;
    background-color: #fff;
    border: 1px solid #e0e0e0;
    border-radius: 45rpx;
    font-size: 32rpx;
    color: #333;
    box-sizing: border-box;
  }

  .answer-btn {
    width: 100%;
    height: 90rpx;
    line-height: 90rpx;
    text-align: center;
    background-color: #fff;
    color: #333;
    border: 1px solid #e0e0e0;
    border-radius: 45rpx;
    font-size: 32rpx;
    transition: all 0.2s;

    &.active {
      background-color: #8c6df6;
      color: #fff;
      border-color: #8c6df6;
      font-weight: 500;
    }
  }
</style>
